/*eslint-disable*/

import axios from 'axios';
import { omit, defaultsDeep, mapValues } from 'lodash';
import store from '../store';

export const instance = axios.create();

instance.defautls = {
	timeout: 10000,
	headers: {
		'content-type': 'application/x-www-form-urlencoded'
	}
};

// loading黑名单
const hideLoadingUrl = ['/bonus_pool', '/super'];

/**
 * 公共请求
 * @param  {string} method 请求方法
 * @param  {string} url    请求地址
 * @param  {object} params  请求参数
 * @return {object}
 */
let loading = 1;
function request(method, url, params = {}) {
	if (!hideLoadingUrl.includes(url)) {
		store.dispatch('show_loading');
	}
	loading++;
	let conf = Object.assign(
		{
			url,
			method,
			data: {}
		},
		instance.defautls
	);
	const headers = {
		'content-type': 'application/json',
		Authorization: `Bearer ${localStorage.getItem('token')}`
	};
	conf.headers = headers;

	// 合并请求代码
	if (method == 'get') {
		conf.params = params;
	} else {
		conf.data = params;
	}

	return Promise.resolve(instance(conf));
}

/**
 * 初始化 axios 配置
 * @return {} [description]
 */
export function setup(opts) {
	const { interceptors } = opts;
	const defautls = omit(opts, 'interceptors');

	if (interceptors && interceptors.response) {
		instance.interceptors.response.use(
			interceptors.response,
			interceptors.errorRep
		);
	}

	if (interceptors && interceptors.request) {
		instance.interceptors.request.use(interceptors.request);
	}

	instance.defautls = defaultsDeep(defautls, instance.defautls);
}

// 替换url中参数
function parseUrl(url, params) {
	return (
		url &&
		url.replace(/\{(\w+)\}/g, (m, n) => {
			return params[n];
		})
	);
}

function maker(method, url) {
	return function(data, params) {
		return request(method, parseUrl(url, params), data);
	};
}

export function method(method) {
	return function(url) {
		return maker(method, url);
	};
}

// 创建请求方法
const [makeGet, makePost, makePut, makeDelete, makePatch] = [
	'get',
	'post',
	'put',
	'delete',
	'patch'
].map(item => {
	return method(item);
});

export const [get, post, put, del] = [
	makeGet,
	makePost,
	makePut,
	makeDelete
].map(action => decorateMaker(action));

/**
 * 错误处理方法
 * @param {function} func 需要修改方法
 * @param {function} rejector 错误时的处理方法
 */
export function decorateMaker(func, rejector) {
	store.dispatch('hide_loading');

	return function() {
		const args = Array.from(arguments);
		let inner = func.apply(null, args);
		return function() {
			const action = inner.apply(null, Array.from(arguments));
			loading--;
			action.finally(() => {
				if (loading === 1) {
					store.dispatch('hide_loading');
				}
			});
			return action;
		};
	};
}
